#include "hall.h"

#include <QJsonDocument>
#include <QJsonObject>

Hall::Hall()
{
    memset(homeTag,0,sizeof(homeTag));
}

ClientArg* Hall::addTcpCommunciationToWaitQue(TcpCommunication *con)
{
    vec.push_back(con);
    if(vec.size()>=2)
    {
        int ret=getHomeId();
        if(ret==-1)
        {
            //没有房间了
        }
        else
        {
            TcpCommunication *first=*vec.begin();
            TcpCommunication *second=*(vec.begin()+1);
            vec.erase(vec.begin());
            vec.erase(vec.begin());
            return play_act(first,second,ret);
        }
    }
    return nullptr;
}

void Hall::connectLeft(TcpCommunication *con)
{
    auto it_find=m_link_hallinfo.find(con);
    if(it_find==m_link_hallinfo.end())
    {
        return;
    }

    string home_name=it_find->second.Hall_name;
    auto it=m_name_hallinfo.find(home_name);
    if(it==m_name_hallinfo.end())
    {
        return;
    }
    m_name_hallinfo.erase(it);
}

ClientArg *  Hall::play_act(TcpCommunication *first,TcpCommunication *second,int home_id)
{
    ClientArg *arg=new ClientArg(home_id, const_cast<Hall*>(this) );
    arg->addTcpCommunication(first);
    arg->addTcpCommunication(second);
    first->setReadArg(arg);
    first->setWriteArg(arg);
    second->setReadArg(arg);
    second->setWriteArg(arg);

    return arg;
}

int Hall::getHomeId()
{
    for(int i=0;i<1024;i++)
    {
        if(homeTag[i]==0)
        {
            homeTag[i]=1;
            return i;
        }
    }
    return -1;
}

void Hall::rollBackId(int id)
{
    homeTag[id]=0;
}

//将tco链接从等待队列中移除
bool Hall::removeInQueue(TcpCommunication *con)
{
    for(vector<TcpCommunication *>::iterator it=vec.begin();it!=vec.end();it++)
    {
        if(*it==con)
        {
            vec.erase(it);
            return true;
        }
    }
    return false;
}

bool  Hall::addSeat(Hall_arg arg,TcpCommunication *creator)
{
    if(creator==nullptr)
    {
        return false;
    }
    //说明有相同的房间 那就让创建房间失败
    if(m_name_hallinfo.find(arg.Hall_name)!=m_name_hallinfo.end()
            || m_link_hallinfo.find(creator)!=m_link_hallinfo.end())
    {
        return false;
    }

    arg.creater=creator;
    m_name_hallinfo[arg.Hall_name]=arg;
    m_link_hallinfo[creator]=arg;
    return true;
}

pair<bool,string>  Hall::joinSeat(string seat_name,string passwd,
                                  TcpCommunication *joiner)
{
    auto name_it=m_name_hallinfo.find(seat_name);
    if(name_it==m_name_hallinfo.end())
    {
        return pair<bool,string>(false,"席位不存在");
    }


    if( name_it->second.Hall_passwd!=passwd)
    {
        return pair<bool,string>(false,"密码错误");
    }
    if(name_it->second.creater==nullptr)
    {
        return pair<bool,string>(false,"席位异常 请选择其他房间");
    }
    if(name_it->second.creater==joiner)
    {
        return pair<bool,string>(false,"自己加入了自己创建的房间");
    }

    if(name_it->second.per !=nullptr)
    {
        return pair<bool,string>(false,"席位已满 请选择其他房间");
    }
    else
    {
        name_it->second.per=joiner;
        auto ret= play_act(m_name_hallinfo[seat_name].creater,m_name_hallinfo[seat_name].per,-1);

        m_link_hallinfo.erase(m_link_hallinfo.find(name_it->second.creater));
        m_name_hallinfo.erase(name_it);


        {
            QJsonObject json;
            json.insert("type",QString("First"));
            QJsonDocument document;
            document.setObject(json);
            QByteArray bytearray = document.toJson(QJsonDocument::Compact);
            ret->first.self->appendQString(bytearray);
            ret->first.status_self=TcpCommunicationStatus::Write;
         }

         {
             QJsonObject json;
             json.insert("type",QString("Second"));
             QJsonDocument document;
             document.setObject(json);
             QByteArray bytearray = document.toJson(QJsonDocument::Compact);
             ret->second.self->appendQString(bytearray);
             ret->first.status_self=TcpCommunicationStatus::Read;
         }
         ret->first.self->changeStatus(TcpCommunication::Status::Write);
         ret->second.self->changeStatus(TcpCommunication::Status::Write);

        return pair<bool,string>(true,"开始对战");
    }

    return pair<bool,string>(false,"异常");
}

vector< pair<string,string>> Hall::getHallDetail()
{
    vector<pair<string,string>> ret;
    for(auto it:m_name_hallinfo)
    {
        ret.push_back(pair<string,string>(it.first,it.second.Hall_desp));
    }
    return ret;
}
